ActiveAdmin.register Wallet do
  config.batch_actions = false
  belongs_to :company
  actions :all, except: [:destroy]
  permit_params :company_id, :name, :overdraw, store_id: []

  filter :name
  action_item :report, only: :index do
    render partial: 'report', locals: { company: params[:q].try(:fetch, 'company_name_contains') }
  end

  index as: :slate do |resource|
    if resource.try(:online)
      div class: 'blank_slate' do
        attributes_table_for resource do
          row :name
          row :amount
          row :overdraw
        end
        div do
          if resource.try(:store_id).blank?
            link_to('查看详细', "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}", class: 'button')
          else
            link_to('查看详细', "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}", class: 'button') +
              link_to('下架', "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}/offline", method: :post, class: 'button warning', data: { confirm: '确定要下架吗？下架之后，该账户下门店会移交至总账户' })
          end
        end
      end
    else
      div class: 'blank_slate offline' do
        attributes_table_for resource do
          row :name
          row :amount
          row :overdraw
        end
        div do
          link_to('查看详细', "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}", class: 'button') +
            link_to('上架', "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}/online", method: :post, class: 'button', data: { confirm: '确定要上架吗？如果该账户门店会已加入其他账户，则会上架失败' })
        end
      end
    end
  end

  show do
    columns do
      column do
        attributes_table do
          row :company
          row '名字' do
            best_in_place resource, :name, {
              as: :input,
              url: "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}",
              ok_button: '确定',
              cancel_button: '取消'
            }
          end
          row :amount do
            number_to_currency(resource.amount, unit: '￥')
          end
          row '透支额度' do
            best_in_place resource, :overdraw, {
              as: :input,
              url: "/admin/companies/#{params[:company_id]}/wallets/#{resource.id}",
              ok_button: '确定',
              cancel_button: '取消',
              display_with: :number_to_currency,
              helper_options: { unit: '￥' }
            }
          end
          row '包含门店' do
            stores = Store.where(id: resource.store_id)
            ul style: 'padding: 0' do
              stores.each do |store|
                li style: 'list-style-type:none;padding: 0.2em' do
                  "<span class='status_tag ok'>#{store.name}</span>&nbsp;
                   <a data-confirm='确定要移除＂#{store.name}＂吗?' rel='nofollow' href='/admin/companies/#{params[:company_id]}/wallets/#{resource.id}/#{store.id}' data-method='delete'>移除</a>
                  ".html_safe
                end
              end
            end
            render partial: 'add_store'
          end
          if resource.try(:online)
            row '当期应付' do
              tps = resource.timetables_provisionals
              stores = tps.pluck(:store_id)
              link_to(number_to_currency(tps.sum(:total), unit: '￥'), "/admin/timetables_provisionals?#{stores.map { |store| format('q[store_id_in][]=%d', store) }.join('&')}")
            end
            row '操作' do
              render 'operation'  if resource.try(:online) && %w[system_admin super_admin].include?(current_admin_user.role)
            end
          end
        end
      end
      column do
        panel '账户记录' do
          paginated_collection(
            WalletTransLog.where(wallet_id: resource.id).select(
              :id, :action, :title, :amount, :remark, :created_at
            ).order(created_at: :desc).page(params[:page]).per(10), param_name: 'page', download: [:xls]
          ) do
            table_for(collection, sortable: false) do
              column :batch_no
              column :action_i18n
              column :title
              column :amount do |item|
                number_to_currency(item.amount, unit: '￥')
              end
              column :remark
              column :created_at
            end
          end
        end
      end
    end
  end

  form do |f|
    bound = Wallet.where(company_id: params[:company_id], online: true).pluck(:store_id).flatten
    unbound = Store.where(company_id: params[:company_id], hidden: false).reject { |store| bound.include?(store.id) }

    f.inputs headline: false do
      f.input :company_id, as: :hidden
      f.input :name
      f.input :overdraw
      f.input :store_id, as: :select, input_html: { multiple: 'multiple' }, collection: unbound.map { |resource| [resource.name, resource.id] }
    end
    f.submit('确定')
  end

  controller do
    def show
      show! and return unless params[:format].eql?('xls')

      company = Company.find_by(id: params[:company_id])
      wallet = Wallet.find_by(id: params[:id])
      book = FastExcel.open(constant_memory: true)
      sheet = book.add_worksheet('账单')
      sheet.write_row(0, %w[编号 行为 类型 内容 额度 备注 详细 记录时间], book.bold_format)
      WalletTransLog.where(wallet_id: params[:id]).order(id: :desc).pluck(
        Arel.sql(
          "id,'{\"0\": \"付款\",\"1\": \"充值\",\"2\": \"收入\",\"3\": \"返利\",\"4\": \"退款\"}'::json ->> action::text,
          '{\"0\": \"周账单\",\"1\": \"详单\",\"2\": \"迟到\",\"3\": \"旷课\",\"4\": \"停课\"}'::json ->> kind::text,
          title, CASE WHEN action=0 THEN -amount ELSE amount END, remark, detail,  created_at"
        )
      ).each { |cols| sheet.append_row(cols) }
      send_data(book.read_string, filename: "#{company.name}-#{wallet.name}-财务流水.xls", type: Mime::Type.lookup_by_extension(:xls))
    end

    def update
      if params[:wallet][:store_id].present?
        wallet = Wallet.find_by(id: params[:id])
        wallet.with_lock do
          wallet.store_id = (wallet.try(:store_id) || []) + params[:wallet][:store_id]
          wallet.save!
        end
        redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}"
      else
        update!
      end
    end

    def offline
      wallet = Wallet.find_by(id: params[:id])
      wallet.with_lock do
        wallet.online = false
        wallet.save!
      end
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}"
    rescue StandardError => e
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}", flash: { notice: e.message }
    end

    def online
      wallet = Wallet.find_by(id: params[:id])
      wallet.with_lock do
        wallet.online = true
        wallet.save!
      end
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}"
    rescue StandardError => e
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}", flash: { notice: e.message }
    end

    def create_log
      log = WalletTransLog.new(log_params)
      log.save!
      need_paying = log.wallet.timetables_provisionals.sum(:total)
      if (log.wallet.amount + log.wallet.overdraw) >= need_paying
        resp = RestClient.post("#{$host[:coach]}/system/command/#{wallet.id}", {})
        flash[:notice] = resp.body.force_encoding('UTF-8')
      end
      redirect_to "/admin/companies/#{params[:wallet_trans_log][:company_id]}/wallets/#{params[:wallet_trans_log][:wallet_id]}"
    rescue StandardError => e
      redirect_to "/admin/companies/#{params[:wallet_trans_log][:company_id]}/wallets/#{params[:wallet_trans_log][:wallet_id]}", flash: { error: "更新钱包失败::#{e.message}" }
    end

    def remove
      wallet = Wallet.find_by(id: params[:id])
      wallet.with_lock do
        wallet.store_id.delete(params[:store_id].to_i)
        wallet.save!
      end
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}"
    rescue StandardError => e
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}", flash: { notice: e.message }
    end

    def pull
      resp = RestClient.post("#{$host[:coach]}/system/command/#{params[:company_id]}/pull", {})
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}", flash: { notice: resp.body.force_encoding('UTF-8') }
    end

    def publish
      resp = RestClient.post("#{$host[:coach]}/system/command/#{params[:id]}", {})
      redirect_to "/admin/companies/#{params[:company_id]}/wallets/#{params[:id]}", flash: { notice: resp.body.force_encoding('UTF-8') }
    end

    def report
      if params[:wallet_trans_log][:report_start_date].blank? || params[:wallet_trans_log][:report_end_date].blank?
        redirect_to '/admin/wallets'
      else
        report_start_date = params[:wallet_trans_log][:report_start_date].to_date
        report_end_date = params[:wallet_trans_log][:report_end_date].to_date
        report_type = params[:wallet_trans_log][:report_type]
        company = Company.find_by(id: params[:wallet_trans_log][:company])
        filter = { created_at_gteq_datetime: report_start_date, created_at_lteq_datetime: report_end_date, company_id_eq: company.try(:id) }

        book = FastExcel.open(constant_memory: true)
        case report_type
        when 'consume'
          sheet = book.add_worksheet(key.name)
          sheet.write_row(0, %w[编号 行为 类型 内容 备注 额度 记录时间], book.bold_format)
          WalletTransLog.ransack(filter.merge(action_eq: :paying)).result.each { |resource| sheet.append_row(resource.values_at(:action_i18n, :kind_i18n, :title, :remark, :amount, :batch_no, :created_at))}
        when 'charge'
          WalletTransLog.ransack(filter.merge(action_in: %w[recharge income rebate refunded])).result.group_by(&:action_i18n).each { |action, resources|
            sheet = book.add_worksheet(action)
            sheet.write_row(0, %w[编号 行为 类型 内容 备注 额度 记录时间], book.bold_format)
            resources.each { |resource| sheet.append_row(resource.values_at(:action_i18n, :kind_i18n, :title, :remark, :amount, :batch_no, :created_at)) }
          }
        else
          WalletTransLog.ransack(filter).result.group_by(&:action_i18n).each { |action, resources|
            sheet = book.add_worksheet(action)
            sheet.write_row(0, %w[编号 行为 类型 内容 备注 额度 记录时间], book.bold_format)
            resources.each { |resource| sheet.append_row(resource.values_at(:action_i18n, :kind_i18n, :title, :remark, :amount, :batch_no, :created_at)) }
          }
        end

        send_data(book.read_string, filename: "#{report_start_date}-#{report_end_date}.xls", type: Mime::Type.lookup_by_extension(:xls))
      end
    end

    protected

    def log_params
      params.require(:wallet_trans_log).permit(:company_id, :wallet_id, :action, :title, :amount, :pay_type, :remark)
    end
  end
end
